/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
* ProgressPanel.java
*
* Created on November 7, 2007, 1:12 AM
 */
package javautil.swing.components;

import javautil.swing.SwingUtil;

import java.beans.PropertyChangeEvent;

import javax.swing.SwingUtilities;

/**
 *
 * @author  stewari1
 */
public class ProgressPanel extends javax.swing.JPanel implements ProgressSupportableListener {

    /** Field description */
    private ProgressSupport progressSupport = null;


    // Variables declaration - do not modify//GEN-BEGIN:variables

    /** Field description */
    private javax.swing.JButton cancelBtn;

    /** Field description */
    private javax.swing.JButton detailsBtn;

    /** Field description */
    private javautil.swing.components.FlexTextArea flexTextArea;

    /** Field description */
    private javax.swing.JProgressBar overAllProgressBar;

    /** Field description */
    private javax.swing.JLabel overAllStatusLabel;

    /** Field description */
    private javax.swing.JProgressBar progressBar;

    /** Field description */
    private javax.swing.JLabel statusLabel;


    // End of variables declaration//GEN-END:variables

    /**
     * Creates new form ProgressPanel
     */
    public ProgressPanel() {

        initComponents();
        flexTextArea.setVisible(false);

        progressSupport = new ProgressSupport(this);
    }

    /**
     * This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */


    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {

        statusLabel        = new javax.swing.JLabel();
        progressBar        = new javax.swing.JProgressBar();
        detailsBtn         = new javax.swing.JButton();
        overAllStatusLabel = new javax.swing.JLabel();
        cancelBtn          = new javax.swing.JButton();
        overAllProgressBar = new javax.swing.JProgressBar();
        flexTextArea       = new javautil.swing.components.FlexTextArea();

        setBorder(javax.swing.BorderFactory.createTitledBorder("Progress"));
        statusLabel.setText(" Progress Information");
        progressBar.setToolTipText("Current Progress");
        detailsBtn.setText("Details >>");
        detailsBtn.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {
                detailsBtnActionPerformed(evt);
            }

        });
        overAllStatusLabel.setText("OverAll Progress Information");
        cancelBtn.setText("Cancel");
        cancelBtn.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelBtnActionPerformed(evt);
            }

        });
        overAllProgressBar.setToolTipText("Overall  Progress");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);

        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(
                layout.createSequentialGroup().addContainerGap().addGroup(
                    layout.createParallelGroup(
                        javax.swing.GroupLayout.Alignment.LEADING).addComponent(
                        flexTextArea, javax.swing.GroupLayout.PREFERRED_SIZE,
                        javax.swing.GroupLayout.DEFAULT_SIZE,
                        javax.swing.GroupLayout.PREFERRED_SIZE).addGroup(
                            layout.createSequentialGroup().addGroup(
                                layout.createParallelGroup(
                                    javax.swing.GroupLayout.Alignment.LEADING).addGroup(
                                    layout.createSequentialGroup().addComponent(
                                        detailsBtn).addPreferredGap(
                                        javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(
                                        cancelBtn).addGap(45, 45, 45)).addGroup(
                                            javax.swing.GroupLayout.Alignment.TRAILING,
                                                layout.createSequentialGroup().addGroup(
                                                    layout.createParallelGroup(
                                                        javax.swing.GroupLayout.Alignment.TRAILING).addComponent(
                                                            statusLabel,
                                                                javax.swing.GroupLayout.Alignment.LEADING,
                                                                    javax.swing.GroupLayout.DEFAULT_SIZE,
                                                                        213,
                                                                        Short.MAX_VALUE).addComponent(
                                                                            overAllStatusLabel,
                                                                                javax.swing.GroupLayout.DEFAULT_SIZE,
                                                                                    213,
                                                                                    Short.MAX_VALUE)).addPreferredGap(
                                                                                        javax.swing.LayoutStyle.ComponentPlacement.RELATED))).addGroup(
                                                                                            layout.createParallelGroup(
                                                                                                javax.swing.GroupLayout.Alignment.LEADING).addComponent(
                                                                                                    progressBar,
                                                                                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                                                                                            183,
                                                                                                            Short.MAX_VALUE).addComponent(
                                                                                                                overAllProgressBar,
                                                                                                                    javax.swing.GroupLayout.DEFAULT_SIZE,
                                                                                                                        183,
                                                                                                                        Short.MAX_VALUE)))).addContainerGap()));
        layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, cancelBtn, detailsBtn);
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(
                layout.createSequentialGroup().addContainerGap(
                    javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE).addGroup(
                    layout.createParallelGroup(
                        javax.swing.GroupLayout.Alignment.LEADING).addComponent(
                        progressBar, javax.swing.GroupLayout.PREFERRED_SIZE,
                        javax.swing.GroupLayout.DEFAULT_SIZE,
                        javax.swing.GroupLayout.PREFERRED_SIZE).addComponent(statusLabel)).addGap(
                            12, 12, 12).addGroup(
                            layout.createParallelGroup(
                                javax.swing.GroupLayout.Alignment.LEADING).addComponent(
                                overAllProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE,
                                javax.swing.GroupLayout.PREFERRED_SIZE).addComponent(
                                    overAllStatusLabel)).addGap(12, 12, 12).addGroup(
                                        layout.createParallelGroup(
                                            javax.swing.GroupLayout.Alignment.BASELINE).addComponent(
                                                detailsBtn).addComponent(
                                                    cancelBtn)).addPreferredGap(
                                                        javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(
                                                            flexTextArea,
                                                                javax.swing.GroupLayout.PREFERRED_SIZE,
                                                                    javax.swing.GroupLayout.DEFAULT_SIZE,
                                                                        javax.swing.GroupLayout.PREFERRED_SIZE)));
        layout.linkSize(javax.swing.SwingConstants.VERTICAL, cancelBtn, detailsBtn);

    }    // </editor-fold>//GEN-END:initComponents

    /**
     * makes the status labels and progress bars blank. this is generally called
     * by a calling code that uses this control at the beginning.
     */
    public void cleanAll() {

        setStatusInfo("");
        setOverAllStatusInfo("");
        showProgressBar(false);
        showOverAllProgressBar(false);
        detailsBtn.setVisible(false);
        cancelBtn.setVisible(false);
    }

    public void openBarsAndButtons() {

        showProgressBar(true);
        showOverAllProgressBar(true);
        detailsBtn.setVisible(true);
        cancelBtn.setVisible(true);
    }

    public ProgressSupport getProgressSupport() {
        return progressSupport;
    }

    public void registerSupport(ProgressSupport... progressSupports) {

        for (ProgressSupport progressSupport : progressSupports) {

            progressSupport.addPropertyChangeListener(ProgressSupport.PROP_PROGRESS, this);
            progressSupport.addPropertyChangeListener(ProgressSupport.PROP_OVERALL_PROGRESS, this);
            progressSupport.addPropertyChangeListener(ProgressSupport.PROP_STATUS_INFO, this);
            progressSupport.addPropertyChangeListener(ProgressSupport.PROP_OVERALL_STATUS, this);
            progressSupport.addPropertyChangeListener(ProgressSupport.PROP_LOG_INFO, this);
            progressSupport.addPropertyChangeListener(ProgressSupport.PROP_SHOW_PROGRESS, this);
            progressSupport.addPropertyChangeListener(ProgressSupport.PROP_SHOW_OVERALL_PROGRESS,
                    this);
        }
    }

    public void propertyChange(PropertyChangeEvent evt) {

        if (ProgressSupport.PROP_PROGRESS.equals(evt.getPropertyName())) {
            setProgress(((Integer) evt.getNewValue()).intValue());
        }

        if (ProgressSupport.PROP_OVERALL_PROGRESS.equals(evt.getPropertyName())) {
            setOverAllProgress(((Integer) evt.getNewValue()).intValue());
        }

        if (ProgressSupport.PROP_STATUS_INFO.equals(evt.getPropertyName())) {
            setStatusInfo((String) evt.getNewValue());
        }

        if (ProgressSupport.PROP_OVERALL_STATUS.equals(evt.getPropertyName())) {
            setOverAllStatusInfo((String) evt.getNewValue());
        }

        if (ProgressSupport.PROP_SHOW_PROGRESS.equals(evt.getPropertyName())) {
            showProgressBar(((Boolean) evt.getNewValue()).booleanValue());
        }

        if (ProgressSupport.PROP_SHOW_OVERALL_PROGRESS.equals(evt.getPropertyName())) {
            showOverAllProgressBar(((Boolean) evt.getNewValue()).booleanValue());
        }

        if (ProgressSupport.PROP_LOG_INFO.equals(evt.getPropertyName())) {
            setLog((String) evt.getNewValue());
        }
    }

    /**
     * Method description
     *
     * @param evt description
     */
    private void cancelBtnActionPerformed(java.awt.event.ActionEvent evt) {    // GEN-FIRST:event_cancelBtnActionPerformed
        progressSupport.setCancel();
    }    // GEN-LAST:event_cancelBtnActionPerformed

    /**
     * Method description
     *
     * @param evt description
     */
    private void detailsBtnActionPerformed(java.awt.event.ActionEvent evt) {    // GEN-FIRST:event_detailsBtnActionPerformed

        flexTextArea.setVisible(!flexTextArea.isVisible());

        switch (detailsBtn.getText()) {

            case "Details >>" :
                detailsBtn.setText("<< Details");

                break;

            case "<< Details" :
                detailsBtn.setText("Details >>");

                break;
        }

        progressSupport.setDetailsAsked(flexTextArea.isVisible());

    }    // GEN-LAST:event_detailsBtnActionPerformed

    /**
     * Method description
     *
     * @param log description
     */
    private void setLog(final String log) {

        Runnable runnable = new Runnable() {

            public void run() {
                flexTextArea.setText(log);
            }
        };

        SwingUtilities.invokeLater(runnable);
    }

    void showProgressBar(final boolean val) {

        Runnable runnable = new Runnable() {

            public void run() {
                progressBar.setVisible(val);
            }
        };

        SwingUtilities.invokeLater(runnable);
    }

    void showOverAllProgressBar(final boolean val) {

        System.out.println("i came here");

        Runnable runnable = new Runnable() {

            public void run() {
                overAllProgressBar.setVisible(val);
            }
        };

        SwingUtilities.invokeLater(runnable);
    }

    void setStatusInfo(final String str) {

        Runnable runnable = new Runnable() {

            public void run() {
                statusLabel.setText(str);
            }
        };

        SwingUtilities.invokeLater(runnable);
    }

    void setOverAllStatusInfo(final String str) {

        Runnable runnable = new Runnable() {

            public void run() {
                overAllStatusLabel.setText(str);
            }
        };

        SwingUtilities.invokeLater(runnable);
    }

    void setProgress(final int progress) {

        Runnable runnable = new Runnable() {

            public void run() {
                progressBar.setValue(progress);
            }
        };

        SwingUtilities.invokeLater(runnable);
    }

    void setOverAllProgress(final int progress) {

        Runnable runnable = new Runnable() {

            public void run() {
                overAllProgressBar.setValue(progress);
            }
        };

        SwingUtilities.invokeLater(runnable);
    }

    public static void main(String[] args) {
        SwingUtil.showFrame(new ProgressPanel());
    }
}
